import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { withLoadingToast } from '@/common/utils'
import { host, key } from '@/common/weather_api'
import { icons } from '@/common/const'

export const useWeatherStore = defineStore('weather', () => {
    // 数据
    const location = ref<any>({
        id: '',
        name: '未知',
        adm1: '',
        adm2: ''
    })
    const latlng = ref('116.39,39.90');
    const center = ref('116.39,39.90,T')

    const updateTime = ref('');
    const now = ref<any>({
        temp: '--',
        feelsLike: '--',
        humidity: '--',
        windDir: '--',
        windScale: '--',
        pressure: '--',
        vis: '--',
        icon: '999',
        text: '--'
    })
    const hourlyData = ref<any[]>(Array.from({ length: 24 }, () => ({ fxTime: '', icon: '999', temp: '--' })))
    const dailyData = ref<any[]>(Array.from({ length: 7 }, () => ({ fxDate: '', iconDay: '999', textDay: '--', textNight: '--', tempMin: '--', tempMax: '--' })));

    const aqi = ref<any>({ category: '--', aqi: '--' })

    // 详情数据
    const detailsData = computed(() => [
        { label: '体感温度', value: `${now.value.feelsLike}°`, icon: icons.feelsLike },
        { label: '相对湿度', value: `${now.value.humidity}%`, icon: icons.humidity },
        { label: '风向', value: now.value.windDir, icon: icons.windDir },
        { label: '风速', value: `${now.value.windScale}级`, icon: icons.windScale },
        { label: '气压', value: `${now.value.pressure}hPa`, icon: icons.pressure },
        { label: '能见度', value: `${now.value.vis}km`, icon: icons.vis }
    ])

    // 方法
    const getLocation = async () => {
        try {
            const res = await new Promise<UniApp.GetLocationSuccess>((resolve, reject) => {
                uni.getLocation({
                    type: 'wgs84',
                    success: resolve,
                    fail: reject
                })
            })
            latlng.value = res.longitude.toFixed(2) + ',' + res.latitude.toFixed(2)
            center.value = res.longitude + "," + res.latitude + ',' + Date.now();
        } catch {
            uni.showToast({ title: '定位失败,启用默认位置', duration: 2000 })
        }
    }

    const getCity = async () => {
        try {
            const api_url = `https://${host}/geo/v2/city/lookup?location=${latlng.value}&key=${key}`
            const res = await new Promise<UniApp.RequestSuccessCallbackResult>((resolve, reject) => {
                uni.request({ url: api_url, method: 'GET', success: resolve, fail: reject })
            })
            const { id, name, adm1, adm2 } = (res.data.location as any[])[0]
            location.value = { id, name, adm1, adm2 }
        } catch (err: any) {
            uni.showToast({ title: '获取城市信息失败:' + (err.errMsg || err), duration: 2000 })
        }
    }

    const getWeather = async () => {
        try {
            const res = await new Promise<UniApp.RequestSuccessCallbackResult>((resolve, reject) => {
                uni.request({
                    url: `https://${host}/v7/weather/now?location=${location.value!.id}&key=${key}`,
                    method: 'GET',
                    success: resolve,
                    fail: reject
                })
            })
            updateTime.value = res.data.updateTime;
            now.value = (res.data as { now: any }).now
        } catch {
            uni.showToast({ title: '获取天气失败', duration: 2000 })
        }
    }

    const getHourlyForecast = async () => {
        try {
            const res = await new Promise<UniApp.RequestSuccessCallbackResult>((resolve, reject) => {
                uni.request({
                    url: `https://${host}/v7/weather/24h?location=${location.value!.id}&key=${key}`,
                    method: 'GET',
                    success: resolve,
                    fail: reject
                })
            })
            hourlyData.value = (res.data as { hourly: any[] }).hourly.slice()
        } catch {
            uni.showToast({ title: '获取小时预报失败', duration: 2000 })
        }
    }

    const getAqi = async () => {
        try {
            const [longitude, latitude] = latlng.value.split(',')
            const res = await new Promise<UniApp.RequestSuccessCallbackResult>((resolve, reject) => {
                uni.request({
                    url: `https://${host}/airquality/v1/current/${latitude}/${longitude}?key=${key}`,
                    method: 'GET',
                    success: resolve,
                    fail: reject
                })
            })
            if (res.data && typeof res.data === 'object' && 'indexes' in res.data && Array.isArray((res.data as any).indexes)) {
                aqi.value = (res.data as any).indexes[0]
            } else {
                aqi.value = null
                uni.showToast({ title: '空气质量数据格式异常', duration: 2000 })
            }
        } catch {
            uni.showToast({ title: '获取空气质量失败', duration: 2000 })
        }
    }

    const get7DaysWeather = async () => {
        try {
            const res = await new Promise<UniApp.RequestSuccessCallbackResult>((resolve, reject) => {
                uni.request({
                    url: `https://${host}/v7/weather/7d?location=${location.value!.id}&key=${key}`,
                    method: 'GET',
                    success: resolve,
                    fail: reject
                })
            })
            dailyData.value = (res.data as { daily: any[] }).daily.slice()
        } catch {
            uni.showToast({ title: '获取未来7天天气失败', duration: 2000 })
        }
    }

    // 初始化
    const init = async () => {
        await withLoadingToast(async () => {
            await getLocation()
            await getCity()
            if (!location.value) {
                uni.showToast({ title: '城市信息获取失败', duration: 2000 })
                return
            }
            await Promise.allSettled([
                getWeather(),
                getHourlyForecast(),
                getAqi(),
                get7DaysWeather()
            ])
        }, '天气更新中', '天气更新成功', '天气更新失败')
    }

    return {
        location, latlng, center, updateTime, now, hourlyData, dailyData, aqi, detailsData,
        getLocation, getCity, getWeather, getHourlyForecast, getAqi, get7DaysWeather, init
    }
}, { persist: true })